package cn.bugstack.infrastructure.repositroy;

import cn.bugstack.domain.strategy.repositroy.IStrategyRepository;
import cn.bugstack.infrastructure.dao.IStrategyAwardDao;
import cn.bugstack.infrastructure.dao.IStrategyDao;
import cn.bugstack.infrastructure.dao.IStrategyRuleDao;
import cn.bugstack.infrastructure.dao.po.Strategy;
import cn.bugstack.infrastructure.dao.po.StrategyAward;
import cn.bugstack.infrastructure.dao.po.StrategyRule;
import cn.bugstack.infrastructure.redis.IRedisService;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyEntity;
import cn.bugstack.domain.strategy.model.entity.StrategyRuleEntity;
import cn.bugstack.types.common.Constants;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.*;

/**
 * 策略仓储实现，基础层依赖领域层，interface位于基础层，实现位于领域层
 */
@Repository
public class StrategyRepositroy implements IStrategyRepository {

	@Resource
	private IStrategyDao strategyDao;
	@Resource
	private IStrategyAwardDao strategyAwardDao;
	@Resource
	private IStrategyRuleDao strategyRuleDao;
	@Resource
	private IRedisService redisService;
	public List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId) {
		// 优先从缓存获取，定义缓存key
		String cacheKey = Constants.RedisKey.STRATEGY_AWARD_LIST_KEY + strategyId;
		// 根据缓存key获取数据，并反序列化为List<StrategyAwardEntity>对象
		List<StrategyAwardEntity> strategyAwardEntities = redisService.getValue(cacheKey);
		if (null != strategyAwardEntities && !strategyAwardEntities.isEmpty()) return strategyAwardEntities;
		// 否则从库中获取数据
		List<StrategyAward> strategyAwards = strategyAwardDao.queryStrategyAwardListByStrategyId(strategyId);
		//指定初始容量为集合大小，避免ArrayList频繁扩容
		strategyAwardEntities = new ArrayList<>(strategyAwards.size());
		for (StrategyAward strategyAward : strategyAwards) {
			StrategyAwardEntity strategyAwardEntity = StrategyAwardEntity.builder()
					.strategyId(strategyAward.getStrategyId())
					.awardId(strategyAward.getAwardId())
					.awardTitle(strategyAward.getAwardTitle())
					.awardSubtitle(strategyAward.getAwardSubtitle())
					.awardCount(strategyAward.getAwardCount())
					.awardCountSurplus(strategyAward.getAwardCountSurplus())
					.awardRate(strategyAward.getAwardRate())
					.sort(strategyAward.getSort())
					.ruleModels(strategyAward.getRuleModels())
					.build();
			strategyAwardEntities.add(strategyAwardEntity);
		}
		//把从数据库中获取到的数据缓存起来
		redisService.setValue(cacheKey, strategyAwardEntities);
		return strategyAwardEntities;
	}

	@Override
	public void storeStrategyAwardSearchRateTables(String key, Integer rateRange, HashMap<Integer, Integer> shuffleStrategyAwardSearchRateTables) {
		//1.存储抽奖策略范围值，如1000，用于生成1000以内的随机数
		redisService.setValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key, rateRange);
		//2.存储概率查找表
		Map<Integer, Integer> cacheRateTable = redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + key);
		cacheRateTable.putAll(shuffleStrategyAwardSearchRateTables);
	}

//	@Override
//	public int getRateRange(Long strategyId) {
//		return getRateRange(String.valueOf(strategyId));
//	}
//
//	@Override
//	public int getRateRange(String key) {
//		int result = redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key);
//		return result;
//	}

	@Override
	public int getRateRange(Long strategyId) {
		return getRateRange(String.valueOf(strategyId));
	}

	@Override
	public int getRateRange(String key) {
		return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + key);
	}

	@Override
	public Integer getStrategyAwardAssemble(String key, Integer rateKey) {
		int result =  redisService.getFromMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + key, rateKey);
		return result;
	}

	@Override
	public StrategyEntity queryStrategyEntityByStrategyId(Long strategyId) {
		//优先从缓存中获取
		String catchKey = Constants.RedisKey.STRATEGY_KEY + strategyId;
		StrategyEntity strategyEntity = redisService.getValue(catchKey);
		if (null != strategyEntity) return strategyEntity;
		Strategy strategy =strategyDao.queryStrategyByStrategyId(strategyId);
		strategyEntity = StrategyEntity.builder()
				.strategyId(strategy.getStrategyId())
				.strategyDesc(strategy.getStrategyDesc())
				.ruleModels(strategy.getRuleModels())
				.build();
		redisService.setValue(catchKey,strategyEntity);
		return strategyEntity;
	}

	@Override
	public StrategyRuleEntity queryStrategyRule (Long strategyId, String ruleModel) {
//		String catchKey = Constants.RedisKey.STRATEGY_RULE_WEIGHT_KEY + strategyId;
//		StrategyRuleEntity strategyRuleEntity = redisService.getValue(catchKey);
//		if (null != strategyRuleEntity || strategyRuleEntity.equals("")) return strategyRuleEntity;
		StrategyRule strategyRuleReq = new StrategyRule();
		strategyRuleReq.setStrategyId(strategyId);
		strategyRuleReq.setRuleModel(ruleModel);
		StrategyRule strategyRuleRes = strategyRuleDao.queryStrategyRule(strategyRuleReq);
		return StrategyRuleEntity.builder()
				.strategyId(strategyRuleRes.getStrategyId())
				.awardId(strategyRuleRes.getAwardId())
				.ruleType(strategyRuleRes.getRuleType())
				.ruleModel(strategyRuleRes.getRuleModel())
				.ruleValue(strategyRuleRes.getRuleValue())
				.ruleDesc(strategyRuleRes.getRuleDesc())
				.build();
	}

	@Override
	public String queryStrategyRuleValue(Long strategyId, Integer awardId, String ruleModel) {
		StrategyRule strategyRule = new StrategyRule();
		strategyRule.setStrategyId(strategyId);
		strategyRule.setAwardId(awardId);
		strategyRule.setRuleModel(ruleModel);
		return strategyRuleDao.queryStrategyRuleValue(strategyRule);
	}


}
